package com.lunago.agent.controller;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.http.server.HttpServerRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lunago.agent.constant.JsonResult;
import com.lunago.agent.constant.ServiceCode;
import com.lunago.agent.ex.ServiceException;
import com.lunago.agent.jwt.JwtPayLoad;
import com.lunago.agent.mapper.UserGemsMapper;
import com.lunago.agent.pojo.dto.PayResultVO;
import com.lunago.agent.pojo.dto.PaySuccessVO;
import com.lunago.agent.pojo.entity.OrderGemsLevel;
import com.lunago.agent.pojo.entity.PermiumOrder;
import com.lunago.agent.pojo.entity.UserGems;
import com.lunago.agent.pojo.entity.UserPermium;
import com.lunago.agent.service.PaymentService;
import com.lunago.agent.service.UserGemsService;
import com.lunago.agent.service.UserPermiumService;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/aichat")
public class PaymentController {

    @Autowired
    private PaymentService paymentService;
    @Autowired
    private UserGemsService userGemsService;
    @Autowired
    UserPermiumService userPermiumService;

    @PostMapping("/premium/status")
    public JsonResult status(@AuthenticationPrincipal JwtPayLoad payload) {
        Long userId = payload.getUserId();
        UserPermium userPremium = userPermiumService.queryUserPermiumByUserId(userId);
        if (userPremium == null) {
            userPremium = new UserPermium();
            userPremium.setStatus(0);
            return JsonResult.ok(userPremium);
        }
        return JsonResult.ok(userPremium);
    }

    @PostMapping("/premium/submit-order")
    public JsonResult submitOrder(@AuthenticationPrincipal JwtPayLoad payload, @RequestBody Dict dict) {
        Long userId = payload.getUserId();
        Integer id = dict.getInt("id");
        Integer count = dict.getInt("count");
        if (id == null || count == null) {
            throw new ServiceException(ServiceCode.ERROR_BAD_REQUEST, "参数错误");
        }
        // 提交订单
        OrderGemsLevel premiumLevel = paymentService.queryPremiumLevelsById(id);
        if (premiumLevel == null) {
            throw new ServiceException(ServiceCode.ERROR_BAD_REQUEST, "参数错误");
        }
        // 验证是否已经是会员
        // if (premiumLevel.getIsPermiumLevel().equals(1)){
        //    UserPermium userPremium = userPermiumService.queryUserPermiumByUserId(userId);
        //    if (userPremium != null && userPremium.getStatus() == 1) {
        //        return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, "您已经是会员了");
        //    }
        // }

        // 生成订单ID
        String orderId = UUID.randomUUID().toString().replace("-", "");
        // 整理参数
        Double totalAmount = premiumLevel.getAmount() * count;
        // 计算ton价格
        Long tonAmount = convertTonAmount(new BigDecimal(totalAmount));
        // 统计payload
        String payLoad = paymentService.getPayLoad(orderId);
        // 执行下订单业务
        PermiumOrder order = new PermiumOrder();
        order.setAmount(Double.valueOf(totalAmount.toString()));
        order.setOrderId(orderId);
        order.setUserId(userId);
        order.setOrderGemsLevelId(id);
        order.setTonAmount(tonAmount);
        paymentService.submitOrder(order);

        // 整理结果
        Map<String, Object> map = new HashMap<>();
        map.put("orderId", orderId);
        map.put("payLoad", payLoad);
        map.put("totalAmount", totalAmount);
        map.put("tonAmount", tonAmount);
        return JsonResult.ok(map);
    }

    private Long convertTonAmount(BigDecimal totalAmount) {
        String tonRateUrl = "https://tonapi.io/v2/rates?tokens=ton&currencies=ton,usd";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<JSONObject> tonRateResponse = restTemplate.getForEntity(tonRateUrl, JSONObject.class);
        if (tonRateResponse.getStatusCode().is2xxSuccessful()) {
            JSONObject body = tonRateResponse.getBody();
            if (body != null && !body.isEmpty()) {
                JSONObject rates = body.getJSONObject("rates");
                if (rates != null) {
                    JSONObject tonObject = rates.getJSONObject("TON");
                    if (tonObject != null) {
                        JSONObject prices = tonObject.getJSONObject("prices");
                        if (prices != null) {
                            BigDecimal usd = prices.getBigDecimal("USD");
                            BigDecimal ton = prices.getBigDecimal("TON");
                            BigDecimal divide = totalAmount.divide(usd, 9, RoundingMode.HALF_EVEN).multiply(ton);
                            return divide.multiply(BigDecimal.valueOf(1000000000)).longValue();
                        }
                    }
                }
            }
        }
        return 0L;
    }

    @PostMapping("/premium-levels")
    public JsonResult premiumLevels() {
        List<OrderGemsLevel> result = paymentService.queryAllPremiumLevels();
        return JsonResult.ok(result);
    }

    @PostMapping("/premium/verify-order")
    public JsonResult verifyOrder(@RequestBody PaySuccessVO checkInputVO) {
        //TODO  验证paypal订单
        String token = checkInputVO.getToken();
        if (token != null) {
            return verifyPayPalOrder(checkInputVO);
        } else {
            return verifyTonOrder(checkInputVO);
        }
    }

    private JsonResult verifyTonOrder(PaySuccessVO checkInputVO) {
        CloseableHttpClient client = HttpClients.createDefault();
        final HttpGet httpGet = new HttpGet("https://toncenter.com/api/v3/transactions?hash=" + URLEncoder.encode(checkInputVO.getTransactionHash()));
        try {
            CloseableHttpResponse httpResponse = client.execute(httpGet);
            //3.获取返回消息体
            HttpEntity entity = httpResponse.getEntity();
            String content = EntityUtils.toString(entity);

            JSONObject bodyObject = JSONObject.parseObject(content);
            JSONArray transactionsArray = bodyObject.getJSONArray("transactions");
            JSONObject transactionObject = transactionsArray.getJSONObject(0);
            JSONArray outMsgsArray = transactionObject.getJSONArray("out_msgs");
            JSONObject firstMsgObject = outMsgsArray.getJSONObject(0);
            String destination = firstMsgObject.getString("destination");
            if (!"0:09F4A9FE3F6DB3266652EBB9B2DF94ACC613635CFC6BC934369E554B5316E119".equals(destination)) {
                return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, "链上收款地址错误");
            }

            /* 校验订单号与链上订单号是否一致 */
            JSONObject message_content = firstMsgObject.getJSONObject("message_content");
            JSONObject decoded = JSONObject.parseObject(message_content.getString("decoded"));
            String comment = decoded.getString("comment");
            if (!comment.equals(checkInputVO.getOrderId().toString())) {
                return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, "订单号错误");
            }

            JSONObject account_state_before = transactionObject.getJSONObject("account_state_before");
            JSONObject account_state_after = transactionObject.getJSONObject("account_state_after");
            long balanceBefore = Long.parseLong(account_state_before.getString("balance"));
            long balanceAfter = Long.parseLong(account_state_after.getString("balance"));
//            /* 校验金额是否大于等于订单金额 */
            JSONObject requestObjectOrderInfo = new JSONObject();
            requestObjectOrderInfo.put("id", checkInputVO.getOrderId());

            /* 查询这笔订单，获取订单金额 */
            PermiumOrder dbOrder =  paymentService.queryPermiumOrderByOrderId(checkInputVO.getOrderId().toString());
            long tonAmount = dbOrder.getTonAmount();
            long web3Amount = balanceBefore - balanceAfter;
            System.out.println("web3Amount:" + web3Amount+ "   -----------tonAmount:" + tonAmount);
            if (web3Amount >= tonAmount) {
                /* 修改订单状态 */
                paymentService.updatePermiumOrderStatus(checkInputVO.getOrderId().toString(), 1);
                /* 更新用户的点数 */
                Integer permiumLevelId = dbOrder.getOrderGemsLevelId();
                paymentService.updateUserGems(dbOrder.getUserId(), permiumLevelId);
                UserGems userGems = userGemsService.queryMyGems(dbOrder.getUserId());
                return JsonResult.ok(userGems);
            } else {
                return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, "支付金额不足");
            }
        } catch (Exception e) {
            return JsonResult.fail(ServiceCode.ERROR_BAD_REQUEST, "内部接口错误");
        }
    }

    private JsonResult verifyPayPalOrder(PaySuccessVO checkInputVO) {
        String token = checkInputVO.getToken();
        PayResultVO payResultVO = paymentService.getOrder(token);
        if (payResultVO.getStatus().equals(1)) {
            /* 查询这笔订单，获取订单金额 */
            PermiumOrder dbOrder =  paymentService.queryPermiumOrderByOrderId(checkInputVO.getOrderId().toString());
            /* 修改订单状态 */
            paymentService.updatePermiumOrderStatus(checkInputVO.getOrderId().toString(), 1);
            /* 更新用户的点数 */
            Integer permiumLevelId = dbOrder.getOrderGemsLevelId();
            paymentService.updateUserGems(dbOrder.getUserId(), permiumLevelId);
            UserGems userGems = userGemsService.queryMyGems(dbOrder.getUserId());
            return JsonResult.ok(userGems);
        }
        return JsonResult.fail(ServiceCode.ERROR_UNKNOWN,"用户暂未成功支付");
    }


}
